#########################################################
## @file   : wifibind.py
## @desc   : check input-device binding files, and export tables can be used in NP platform
## @create : 2021/08/07
## @author : Chengan
## @email  : douboer@gmail.com
#########################################################

import re
import sys
import os
import io
import json
import time
import logging
import platform
import subprocess
import openpyxl
import argparse

from collections import defaultdict

# define constants
SSID_PREF_TYPE   = 0 # 0 - position; 1 - 'aWiFi'; 2 - i-zhejiang
ROOT_PATH        = './'

DEBUG            = 1   # 0 - INFO; 1 - DEBUG
LOG2FILE         = 1   # 0 - to stdio; 1 - to file
LOGFILE          = os.path.join(ROOT_PATH,'log.wifibind.txt')
DEVICE_FOLDER    = os.path.join(ROOT_PATH,'devices')
INPUT_FOLDER     = os.path.join(ROOT_PATH,'input')
OUTPUT_FOLDER    = os.path.join(ROOT_PATH,'output')
MAC_MODEL_TABLE  = os.path.join(ROOT_PATH,'config','MAC型号.csv')
MAC_MODEL_FROML  = os.path.join(ROOT_PATH,'config','macfroml.json')

MODELS = {
        0 :{'model':'MR820','factory':'Fiberhome','offset':-3},
        1 :{'model':'MR820-LK','factory':'Fiberhome','offset':-1},
        2 :{'model':'MR622-BJ','factory':'Fiberhome','offset':1},
        3 :{'model':'MR622-BJ','factory':'Fiberhome','offset':1},
        4 :{'model':'MR622-KK','factory':'Fiberhome','offset':-8},
        5 :{'model':'B860GV1.1','factory':'ZTE','offset':2},
        6 :{'model':'E910V10C','factory':'SKYWORTH','offset':1},
        7 :{'model':'E910V10C$88CC45','factory':'SKYWORTH','offset':1532712},
        8 :{'model':'DT741','factory':'SKYWORTH','offset':1},
        9 :{'model':'RG020ET-CA','factory':'NSB','offset':-7},
        10:{'model':'ZN802','factory':'ZN','offset':-15}}
'''

MODELSCN = {
    'MR820':{'factory':'烽火','offset':-3},
    'MR820-LK':{'factory':'烽火','offset':-1},
    'MR622-BJ-GPON':{'factory':'烽火','offset':9},
    'MR622-BJ-IPTV':{'factory':'烽火','offset':1},
    'MR622-KK':{'factory':'烽火','offset':-8},
    'B860GV1.1':{'factory':'中兴','offset':2},
    'E910V10C':{'factory':'创维','offset':1},
    'E910V10C$88CC45':{'factory':'创维','offset':1532712},
    'DT741':{'factory':'创维','offset':1},
    'RG020ET-CA':{'factory':'诺基亚贝尔'-7,'offset':},
    'ZN802':{'factory':'兆能','offset':-15}
}
'''

'''
Q:
1. 拼接作用&规则？ xxxx
2. SSID是否固定是酒店缩写+房间号  xxxx
3. 输入表检查什么？房间号、MAC、电话格式  xxxx
4. NP导入表是哪张？输出：NP导入表 + 错误表  xxxx
5. MAC前六位对应多个型号，如何选择？ xxxx
6. 'MR622-BJ-GPON', 'MR622-BJ-IPTV' 区分规则？从网管?
'''

# log info
logger = logging.getLogger()
#formatter = logging.Formatter
#    ('%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s')
formatter = logging.Formatter('')

if LOG2FILE:
    handler = logging.FileHandler(LOGFILE)
    handler.setFormatter(formatter)
    logger.addHandler(handler)
else:
    logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)

if DEBUG:
    logger.setLevel(logging.DEBUG)

#data structure - customer table

class WifiBind:

    def __init__(self,parent=None):
        self.MAC_DICT = self.json2dict(MAC_MODEL_FROML)

        # define some init params
        self.input_file = ''
        self.input_files = []
        self.output_file = ''
        self.parse_by_column = False

        pass

    # check whether or not include cn
    def check_cn(self, istr):
        rcn = re.compile(u'[\u4e00-\u9fa5]')
        return rcn.search(istr)

    # 表样,酒店房间号,ITV业务帐号,"宽带号（宽带账号）",设备MAC地址,联系人,"联系电话（管理员手机、唯一、作为爱WiFi商户手机号）","酒店名称 （酒店实际经营名称，名牌）","酒店地址（按规范填写，例：浙江省杭州市下城区将军路1号）","酒店缩写（用于SSID）",省,市,区,终端型号
    # 6101,1572108467283418,057267284566,F8AFDB1BD6F0,余珍,18768473481,湖州含韵酒店管理有限公司,浙江省湖州市吴兴区外环东路368号1-7幢,rujia,浙江,湖州,吴兴区,MR622-KK
    def parse_customer_table(self, ifn):
        """parse customer tables
        Args: ifn, input file
        Return: defaultdict, customer data structure
        """
        logger.debug('parse customer table from file {} ... '.format(ifn))

        mdict = defaultdict(dict)
        mcustomerdict = defaultdict(dict)
        posdict = defaultdict(dict)
        if re.search(r'xlsx{0,1}$',ifn):
            mwb = openpyxl.load_workbook(ifn)
            sheetnames = mwb.sheetnames
            ws = mwb[sheetnames[0]]

            logger.info('input xls {} num lines {} num columns {}'.format(ifn, ws.max_row, ws.max_column))

            posdict = {'roomnum':{'pos':-1,'key':'房间号'},
                    'itvaccount':{'pos':-1,'key':'ITV'},
                    'bbaccount':{'pos':-1,'key':'^宽带'},
                    'mac':{'pos':-1,'key':'MAC'},
                    'contact':{'pos':-1,'key':'联系人'},
                    'phone':{'pos':-1,'key':'^联系电话'},
                    'hotelname':{'pos':-1,'key':'酒店.*名称'},
                    'hoteladdr':{'pos':-1,'key':'酒店地址'},
                    'abbr':{'pos':-1,'key':'酒店缩写'},
                    'province':{'pos':-1,'key':'(浙江){0,1}省(（必填）){0,1}$'},
                    'city':{'pos':-1,'key':'^市'},
                    'district':{'pos':-1,'key':'^区'},
                    'model':{'pos':-1,'key':'终端型号'}}

            for i, row in enumerate(ws.iter_rows()):
                errinfo = ''
                if i == 0: # header
                    for j, cell in enumerate(row):
                        if cell.value is None: continue
                        #print(cell.value)
                        for _,p in posdict.items():
                            if re.search(p['key'],cell.value):
                                p['pos'] = j
                                break
                    continue
                posdict['city']['pos'] = posdict['province']['pos']+1
                posdict['district']['pos'] = posdict['province']['pos']+2

                ##### check position, and handle exception, to be implement!!
                if not self.parse_by_column:
                    [posdict['roomnum']['pos'],
                    posdict['itvaccount']['pos'],
                    posdict['bbaccount']['pos'],
                    posdict['mac']['pos'],
                    posdict['contact']['pos'],
                    posdict['phone']['pos'],
                    posdict['hotelname']['pos'],
                    posdict['hoteladdr']['pos'],
                    posdict['abbr']['pos'],
                    posdict['province']['pos'],
                    posdict['city']['pos'],
                    posdict['district']['pos'],
                    posdict['model']['pos']] = [posdict['roomnum']['pos']+x for x in range(0,13)]

                # XXX
                #print(posdict)

                # 忽略空行
                [rowlist, tlist] = [[],[]]
                for cell in row:
                    if cell.value is None: tlist.append('')
                    else:
                        tlist.append(str(cell.value))
                if re.match(r'^\s*$',''.join(tlist)): continue

                # 检查空字段

                for cell in row: rowlist.append(cell.value)

                flg = False
                imac = ''.join(re.split(r'[:-;,；： ]', tlist[posdict['mac']['pos']])).upper()
                if not re.match(r'^[-0-9a-zA-Z]{1,10}$', str(tlist[posdict['roomnum']['pos']])):
                    errinfo += ' 房间号:' + tlist[posdict['roomnum']['pos']] + ' 格式有误;'
                    flg = True
                if not re.match(r'^[0-9A-Z]{12}$', imac):
                    errinfo += ' MAC:' + tlist[posdict['mac']['pos']] + ' 格式有误;'
                    flg = True
                if not re.match(r'^[-0-9a-zA-Z]{1,10}$', tlist[posdict['abbr']['pos']]):
                    errinfo += ' 房间缩写:' + tlist[posdict['abbr']['pos']] + ' 格式有误;'
                    flg = True
                if not re.match(r'^[0-9]{11}$', str(tlist[posdict['phone']['pos']])):
                    errinfo += ' 电话号码:' + tlist[posdict['phone']['pos']] + ' 格式或长度有误;'
                    flg = True

                # check duplication record
                mdict[imac].setdefault('num',0)   # !!! good trick
                mdict[imac]['num'] += 1
                if mdict[imac]['num'] > 1:
                    errinfo += ' MAC:' + tlist[posdict['mac']['pos']] + ' 重复;'
                    flg = True

                # check prefix 6 bit of MAC ==> multi model

                '''
                if flg:
                    logger.info("ERROR: line {} ({}) format error!".format(i, errinfo))
                    continue
                '''

                #房间号,ITV*账号,宽带*账号,MAC,联系人,联系电话,酒店*名称,酒店地址,酒店缩写,省,市,区,终端型号
                mdict[imac]['roomnum'] = rowlist[posdict['roomnum']['pos']]
                mdict[imac]['itvaccount'] = rowlist[posdict['itvaccount']['pos']]
                mdict[imac]['bbaccount'] = rowlist[posdict['bbaccount']['pos']]
                mdict[imac]['mac'] = rowlist[posdict['mac']['pos']]
                mdict[imac]['contact'] = rowlist[posdict['contact']['pos']]
                mdict[imac]['phone'] = rowlist[posdict['phone']['pos']]
                mdict[imac]['hotelname'] = rowlist[posdict['hotelname']['pos']]
                mdict[imac]['hoteladdr'] = rowlist[posdict['hoteladdr']['pos']]
                mdict[imac]['abbr'] = rowlist[posdict['abbr']['pos']]
                mdict[imac]['province'] = rowlist[posdict['province']['pos']]
                mdict[imac]['city'] = rowlist[posdict['city']['pos']]
                mdict[imac]['district'] = rowlist[posdict['district']['pos']]
                mdict[imac]['model'] = rowlist[posdict['model']['pos']]
                mdict[imac]['errinfo'] = errinfo

                # MAC重复记录，errorinfo信息不同，必须拷贝对象
                mcustomerdict[i][imac] = mdict[imac].copy()

        '''
        "1": {"5CE3B60359BF": {
        "abbr": "SFT",
        "bbaccount": "057667498607",
        "city": "台州",
        "contact": "李雪建",
        "customermanager": "项婷婷",
        "district": "临海市",
        "errinfo": "",
        "hoteladdr": "浙江省台州市临海市杜桥镇杜前路",
        "hotelname": "临海市索菲特大酒店有限公司",
        "itvaccount": "tv1576189267498058@itv",
        "mac": "5c:e3:b6:03:59:bf",
        "model": "烽火MR820",
        "num": 1,
        "office": "杜桥分局",
        "phone": 13655863323,
        "province": "浙江",
        "roomnum": 501,
        "servicename": "王梦杰",
        "servicephone": 15356558857
        },
        '''
        return mcustomerdict

    def process_output_table(self, ifn, ofn):
        ## read customer information
        customer_dict = mwb.parse_customer_table(ifn)
        logger.debug('parse customer table ')
        logger.debug(json.dumps(customer_dict, indent=4, sort_keys=True, ensure_ascii=False))

        ## write to result table
        wb = openpyxl.Workbook()
        ws = wb.active
        #ws = wb.create_sheet("sheet")
        #ws = wb.create_sheet("sheet", 0)
        header = ["设备mac","宽带账号","商户账号(手机号)","商户名称","一级行业","二级行业","联系人","联系方式","商户地址","设备SSID(例:yx-123)","省(例:浙江)","市(例:杭州)","区(例:西湖区)","经度","纬度","商户名称缩写","房间号","错误信息"]
        ws.append(header)

        jointmac = ''
        mdre = re.compile(r'''[-\.0-9a-zA-Z]+''', flags=re.X)
        fw = open(os.path.join(ROOT_PATH,'joint.txt'), "a")
        for k, v in customer_dict.items():
            mmac = list(v.keys())[0]
            mwifimac = self.trans_awifi_mac2(mmac)
            errorinfo = v[mmac]['errinfo']

            if isinstance(mwifimac, int):
                if mwifimac>1 or mwifimac==-1:
                    if mwifimac==-1:
                        errorinfo += 'MAC前六位匹配不到型号，依据客户提供表格获取型号; '
                    else:
                        errorinfo += 'MAC前六位匹配多个型号，依据客户提供表格获取型号; '

                    # 尝试从用户表中获取型号
                    mmodel = ''
                    if not v[mmac]['model'] is None:
                        mmodel = mdre.search(v[mmac]['model']).group(0)
                    else:
                        errorinfo += '客户提供表格型号信息不存在; '
                        mwifimac = mmac

                    midx = self.get_model_idx(mmodel)
                    if midx is None:
                        errorinfo += '客户提供表格型号信息不准确; '
                        mwifimac = mmac
                    else:
                        errorinfo += '客户提供型号:{}'.format(mmodel)
                        mwifimac = self.trans_awifi_mac(midx, mmac)

                elif mwifimac==0:
                    mwifimac = mmac

            content = [mwifimac,
                     v[mmac]['bbaccount'],
                     v[mmac]['phone'],
                     v[mmac]['hotelname'],
                     '完美酒店','星级',   # 哪里来？
                     v[mmac]['contact'],
                     v[mmac]['phone'],
                     v[mmac]['hoteladdr'],
                     '-'.join([str(v[mmac]['abbr']),str(v[mmac]['roomnum'])]),
                     v[mmac]['province'],
                     v[mmac]['city'],
                     v[mmac]['district'],
                     '','',  #经纬度哪里来
                     v[mmac]['abbr'],v[mmac]['roomnum'],
                     errorinfo]
            ws.append(content)

            jointmac += mwifimac
            jointmac += ','

        print(jointmac, '\n')

        # write joint mac to joint.txt file
        fw.write(ofn+'\n')
        fw.write(jointmac)
        fw.write('\n\n')
        fw.close()

        wb.save(ofn)

    # convenient to find offset from MODELS dict
    def get_model_idx(self,md):
        for k,v in MODELS.items():
            if md in v['model']: return k

        return None

    # "9": { "factory": "NSB", "offset": -7, "model": "RG020ET-CA", "pre_mac_list": [ "6CEFC6", ...] },
    # discard XXXXXXXXX,,, substitude by json file which obtained from all device tables
    def parse_mac_model_table(self, mpt):
        macmodeldict = defaultdict(dict,MODELS)

        # {idx:model}
        for i, k in enumerate(MODELS.keys()): macmodeldict[i]['pre_mac_list'] = []

        with open(mpt, 'r', encoding='utf8', errors='ignore') as f:
            flg = False
            for line in f.readlines():
                if not flg:
                    flg = True
                    continue # skip header

                line = line.strip()
                if re.match(r'^\s*$',line): continue

                mac_pre_list = line.split(',')
                for i, v in enumerate(mac_pre_list):
                    if not re.match(r'^[0-9A-Z]{6}$', v): continue
                    macmodeldict[i-1]['pre_mac_list'].append(v)

        # "6": { "factory": "SKYWORTH", "model": "E910V10C", "offset": 1, "pre_mac_list": [ "0050FD",
        # => "74C9A3": { "factory": "Fiberhome", "model": [ "MR622-BJ", "MR820" ] }, },
        '''
        tdict = defaultdict(dict)
        for k, v in macmodeldict.items():
            for mpre in v['pre_mac_list']:
                tdict[mpre]['factory'] = v['factory']
                tdict[mpre].setdefault('model',[]).append(v['model'])
        logger.debug("ttttttdict")
        logger.debug(json.dumps(tdict, indent=4, sort_keys=True, ensure_ascii=False))
        '''

        '''
        # read json mac prefix data, append to macmodeldict
        # json dict: {"2C1875": {"mac": "2C1875AFE0C9", "factory": "SKYWORTH", "model": "E910V10C"},.. 
        for k, v in self.json2dict(MAC_MODEL_FROML).items():
            i = self.get_model_idx(v['model'])
            if i is not None:
                if not k in macmodeldict[i]['pre_mac_list']: macmodeldict[i]['pre_mac_list'].append(k)

        # logger.debug(json.dumps(macmodeldict, indent=4, sort_keys=True, ensure_ascii=False))
        '''

        return macmodeldict

    # parse all device tables in order to obtain the relationship between mac prefix and model
    def parse_devices_table(self, mpt):
        """parse all devices files, and get the features of devices
        Args: mpt is path of the devices folder
        Return: dict
        """

        # { "049573": { "factory": "ZTE", "mac": "049573338157", "model": "B860GV1.1_2" },}
        devicedict = defaultdict(dict)
        # { "MR820": { "factory": "", "mac": "5CE3B612E8D7", "model": "MR820" },}
        devicemodeldict = defaultdict(dict)

        mfiles = self.list_files(mpt)

        for mfn in mfiles:
            logger.debug('loop file name {} ... '.format(mfn))
            if re.search(r'xlsx{0,1}$',mfn):

                ## CGDBG, slowly, discard
                continue

                mwb = openpyxl.load_workbook(mfn)
                sheetnames = mwb.sheetnames
                ws = mwb[sheetnames[0]]

                logger.debug('Test xls num lines {} num columns {}'.format(ws.max_row, ws.max_column))
                for row in ws.iter_rows():
                    # logger.debug('{} {} {}'.format(row[0].value,row[3].value,row[4].value))
                    if row[0].value is None or row[3].value is None or row[4].value is None: continue

                    mac = ''.join(re.split(r'[:-;,；： ]', row[0].value)).upper()
                    model = '-'.join([row[3].value, row[4].value])

                    if not re.match(r'^[0-9A-Z]{12}$', mac): continue
                    mac_pre = mac[0:6]

                    '''
                    devicedict['mac_pre'] = devicedict['mac'][0:6].upper()
                    devicedict['factory'] = row[3].value
                    devicedict['model'] = row[4].value
                    '''

                    devicedict[mac_pre]['mac'] = mac
                    devicedict[mac_pre]['factory'] = row[3].value
                    devicedict[mac_pre]['model'] = row[4].value

                    devicemodeldict[model]['mac'] = mac
                    devicemodeldict[model]['factory'] = row[3].value
                    devicemodeldict[model]['model'] = row[4].value

                mwb = None
            elif re.search(r'csv$',mfn):
                with open(mfn, 'r', encoding='utf8', errors='ignore') as f:
                    idx = 0
                    for line in f.readlines():
                        line = line.strip()
                        if re.match(r'^\s*$',line): continue

                        devicelist = line.split(',')

                        mac = ''.join(devicelist[0].split(':')).upper()
                        model = '-'.join([devicelist[3], devicelist[4]])

                        if not re.match(r'^[0-9A-Z]{12}$', mac): continue
                        mac_pre = mac[0:6]

                        devicedict[mac_pre]['factory'] = devicelist[3]
                        #devicedict[mac_pre]['model'] = devicelist[4]
                        devicedict[mac_pre].setdefault('model',[]).append(devicelist[4])

                        devicemodeldict[model]['mac_pre'] = mac_pre
                        devicemodeldict[model]['factory'] = devicelist[3]
                        devicemodeldict[model]['model'] = devicelist[4]

                        idx += 1
                    logger.debug('Test csv num lines {} '.format(idx))

        # delete duplication model
        for k, v in devicedict.items():
            # mnum = len(v['model'])
            modellist = list(set(v['model']))
            devicedict[k]['model'] = modellist

        logger.debug(json.dumps(devicedict, indent=4, sort_keys=True, ensure_ascii=False))
        logger.debug(json.dumps(devicemodeldict, indent=4, sort_keys=True, ensure_ascii=False))

        return devicedict

    # MODELS - { 0 :{'model':'MR820','factory':'Fiberhome','offset':-3},
    # mac format: XXXXXXXXXXXX
    def trans_awifi_mac(self, mmodelidx, mmac):
        if not re.match(r'^[0-9A-Z]{12}$', mmac): return 0

        moffset = MODELS[mmodelidx]['offset']
        pre6 = mmac[0:6]
        suf6 = mmac[6:12]
        suf6trans = hex(int(suf6, 16)+int(moffset))[2:]  # skip 0x

        #print('{} {} {} {}'.format(mmodelidx, moffset, mmac.upper(),''.join([pre6,suf6trans.zfill(6)]).upper()))

        return ''.join([pre6,suf6trans.zfill(6)]).upper()

    # 0: mac format error
    # -1: mac prefix not found mac-model table
    # >1: mac_pre => multiple model
    def trans_awifi_mac2(self, mmac):
        if not re.match(r'^[0-9A-Z]{12}$', mmac): return 0

        mmodel_mac_dict = self.get_model_macs_dict()
        mmac_pre = mmac[0:6]
        modellist = []
        try:
            modellist = self.MAC_DICT[mmac_pre]['model']
        except KeyError as e:
            # print(e)
            return -1

        if not len(modellist)==1:
            return len(modellist)

        if mmac_pre=='88CC45': tidx = 7  # special mac
        else: tidx = mmodel_mac_dict[modellist[0]]['idx']
        return self.trans_awifi_mac(tidx, mmac)

    # MAC长度不足，补零规则？ XXXX

    # input directory, return all files included
    def list_files(self, mpt):
        mfiles = []
        mlist = os.listdir(mpt)
        for i in range(0, len(mlist)):
            path = os.path.join(mpt, mlist[i])
            if os.path.isdir(path):
                mfiles.extend(self.list_files(path))
            if os.path.isfile(path):
                _, basename = os.path.split(path)
                if basename.startswith('.'): continue
                mfiles.append(path)
        return mfiles

    # convert dict to json 
    # Return: json string
    def dict2json(self,d):
        jstr = json.dumps(d)
        return jstr

    # convert dict to json 
    # jf is the file saved json string
    # Return: dict
    def json2dict(self,jf):
        d = {}
        with open(jf, 'r', encoding='utf8', errors='ignore') as f:
            d=json.load(f)
        return d

    # return: {"9": { "factory": "NSB", "offset": -7, "model": "RG020ET-CA", "pre_mac_list": [ "6CEFC6", ...] },
    def get_index_model_dict(self):
        # mdict  mac_pref - model, parse from json file
        # {'049573': {'factory': 'ZTE', 'model': ['B860GV1.1']},
        midx_model_dict = defaultdict(dict)
        for k,v in self.MAC_DICT.items():
            for mmodel in v['model']:
                for midx,mv in MODELS.items():
                    if mmodel in mv['model']:
                        midx_model_dict[midx].setdefault('pre_mac_list',[]).append(k)
                        midx_model_dict[midx]['model'] = mv['model']
                        midx_model_dict[midx]['factory'] = mv['factory']
                        midx_model_dict[midx]['offset'] = mv['offset']
                        break

        return midx_model_dict

    # return: { "B860GV1.1": { "factory": "ZTE", "idx": 5, "mac": 2, "pre_mac_list": [ "049573",...]}}
    def get_model_macs_dict(self):
        # parse from the result of get_index_model_dict()
        mmodel_mac_dict = defaultdict(dict)
        for k, v in self.get_index_model_dict().items():
            mmodel_mac_dict[v['model']]["idx"] = k
            mmodel_mac_dict[v['model']]["factory"] = v['factory']
            mmodel_mac_dict[v['model']]["pre_mac_list"] = v['pre_mac_list']
            mmodel_mac_dict[v['model']]["offset"] = v['offset']

        return mmodel_mac_dict

    # wifibind.py -i file1.xls,file2.xlsx
    def parse_files_list(self, argv):
        parser = argparse.ArgumentParser(description="WiFi bind script ")
        parser.add_argument('-i', action='store', dest='ifiles', help='input file list seperated with ,')
        parser.add_argument('-c', action='store_true', default=False, dest='switch',
                help='switch to parse table by column name')
        parser.add_argument('-C', action='store_true', default=False, dest='switch',
                help='switch to parse table by column name')
        result = parser.parse_args()
        #print('boolean_switch {}'.format(result.switch))
        self.parse_by_column = result.switch

        if result.ifiles is None: return []

        flist = [x.strip() for x in re.split(r'[;,]+', result.ifiles)]
        fflist = []

        for f in flist:
            if re.match(r'^.+.xls[x]{0,1}$', f):
                fflist.append(f)

        return fflist

## XXXXXXXXXXXXX
def only_for_debug(mwb):
    import time
    localtime = time.asctime( time.localtime(time.time()) )
    logger.debug('\n==================== {} ======================='.format(localtime))

    '''
    dtab = mwb.parse_devices_table(DEVICE_FOLDER)
    #find mac prefix list in device table and write to json file
    logger.debug("parsing device table")
    with open(MAC_MODEL_FROML, 'w', encoding='utf8', errors='ignore') as fw:
        fw.write(mwb.dict2json(dtab))
    '''

    # {'049573': {'factory': 'ZTE', 'model': ['B860GV1.1']},
    #mac_dict = mwb.json2dict(MAC_MODEL_FROML)
    #logger.debug("printing mac_dict")
    logger.debug(json.dumps(mwb.MAC_DICT, indent=4, sort_keys=True, ensure_ascii=False))

    # "9": { "factory": "NSB", "offset": -7, "model": "RG020ET-CA", "pre_mac_list": [ "6CEFC6", ...] },
    '''
    idx_model_dict = mwb.parse_mac_model_table(MAC_MODEL_TABLE)
    logger.debug("printing idx_model_dict")
    logger.debug(json.dumps(idx_model_dict, indent=4, sort_keys=True, ensure_ascii=False))
    '''
    idx_model_dict = mwb.get_index_model_dict()
    logger.debug("printing idx_model_dict")
    logger.debug(json.dumps( idx_model_dict, indent=4, sort_keys=True, ensure_ascii=False))

    #{ "B860GV1.1": { "factory": "ZTE", "idx": 5, "mac": 2, "pre_mac_list": [ "049573",...]}}
    model_mac_dict = mwb.get_model_macs_dict()
    logger.debug("printing model_mac_dict")
    logger.debug(json.dumps(model_mac_dict, indent=4, sort_keys=True, ensure_ascii=False))

    # {"2C1875": {"factory": "SKYWORTH", "model": "E910V10C"},.. 
    # rewite mac_dict include all data
    '''
    mac_dict = None
    mac_dict = defaultdict(dict)
    for k, v in model_mac_dict.items():
        for mpremac in v['pre_mac_list']:
            mac_dict[mpremac]['factory'] = v['factory']
            mac_dict[mpremac]['model'] = k
    logger.debug("refill mac_dict")
    logger.debug(json.dumps(mac_dict, indent=4, sort_keys=True, ensure_ascii=False))
    '''

    #################################################################
    ## test mac translate
    #################################################################
    mwb.trans_awifi_mac(1, '6C9E7CCCCCCC')   # '6C9E7CCCCCCB'
    mwb.trans_awifi_mac(9, '5CE3B6AAAAAA')   # '5CE3B6AAAAA3'
    mwb.trans_awifi_mac(2, '18D225BBBBBB')   # '18D225BBBBC4'
    mwb.trans_awifi_mac(7, '88CC45DDDDDD')   # '88CC45F54105'
    #tmac = '88CC45DDDDDD'
    tmac = '5CE3B6AAAAAA'
    tidx = model_mac_dict[mwb.MAC_DICT[tmac[0:6]]['model'][0]]['idx']
    mwb.trans_awifi_mac(tidx, tmac)   # 5CE3B6AAAAA7'
    print(mwb.trans_awifi_mac2('5CE3B6AAAAAA'))  # 5CE3B6AAAAA7
    print(mwb.trans_awifi_mac2('88CC45DDDDDD'))  # 88CC45F54105
    #################################################################


    #################################################################
    ## test write to result table
    #################################################################
    ifn = './input/0101客户表.xlsx'
    ofn = './output/test.xlsx'
    mwb.process_output_table(ifn, ofn)
    #################################################################

    pass

if __name__=='__main__':

    mwb = WifiBind()

    filelist = mwb.parse_files_list(sys.argv)

    for f in filelist:
        ifn = os.path.join(INPUT_FOLDER, f)
        ofn = os.path.join(OUTPUT_FOLDER, 'output_'+f)
        #print('ifn {} ofn {} '.format(ifn,ofn))
        if not os.path.exists(ifn):
            logger.info('input file {} is not existed '.format(ifn))
            continue

        mwb.process_output_table(ifn, ofn)

    #only_for_debug(mwb)

